package com.study.web.shiro.realm;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;

import com.study.common.exception.BizException;
import com.study.web.dto.PermissionDto;
import com.study.web.entity.SysRole;
import com.study.web.entity.SysUser;
import com.study.web.service.syspermission.SysPermissionService;
import com.study.web.service.sysrole.SysRoleService;
import com.study.web.service.sysuser.SysUserService;
/**
 * Created by ryhx.ZhangCheng on 2017/5/5.
 *
 * @remark 自定义realm
 */
@SuppressWarnings("all")
public class RyhxRealm extends AuthorizingRealm {

	@Resource
	private SysUserService sysUserService;
	
	@Resource
	private SysRoleService sysRoleService;
	
	@Resource
	private SysPermissionService sysPermissionService;
	
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException,BizException {
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        SysUser sysUser=new SysUser();
        if(StringUtils.isEmpty(token.getUsername())){
        	throw BizException.PARAM_NULL_ERROR;
        }
        sysUser.setLoginName(token.getUsername());
        SysUser sysUserDataBase = sysUserService.getSystemUserByExmaple(sysUser);
        if(sysUserDataBase==null){
            throw  new UnknownAccountException();
        }
        if(sysUserDataBase != null && sysUserDataBase.getStatus() == 2){
            throw new LockedAccountException("当前账户已冻结，无法登陆系统！");
        }
        // 认证缓存信息
        return new SimpleAuthenticationInfo(sysUserDataBase, sysUserDataBase.getPassword().toCharArray(), getName());
    }

    /**
     * Shiro权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) throws BizException{
        SysUser shiroUser = (SysUser) principals.getPrimaryPrincipal();
        SysRole sysRole = sysRoleService.getById(shiroUser.getRoleId());
        Map<String, Object> allUseableRolePermisssonParamMap = new HashMap<String, Object>();
        allUseableRolePermisssonParamMap.put("status", 1);
        allUseableRolePermisssonParamMap.put("roleId", shiroUser.getRoleId());
        List<PermissionDto> allUseableRolePermissson = sysPermissionService.queryPermisssonOfRole(allUseableRolePermisssonParamMap);//角色所有可用的权限
        Set<String> urlSet = new HashSet<String>();
        for (PermissionDto permissionDto : allUseableRolePermissson) {
        	if(!"0".equals(permissionDto.getHashPermission())){
        		urlSet.add(permissionDto.getPermission());
        	}
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRole(sysRole.getEnName());
        info.addStringPermissions(urlSet);
        return info;
    }
    
    /**
     * 清空当前用户权限信息
     */
	public  void clearCachedAuthorizationInfo() {
		PrincipalCollection principalCollection = SecurityUtils.getSubject().getPrincipals();
		SimplePrincipalCollection principals = new SimplePrincipalCollection(
				principalCollection, getName());
		super.clearCachedAuthorizationInfo(principals);
	}
	/**
	 * 指定principalCollection 清除
	 */
	public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) {
		SimplePrincipalCollection principals = new SimplePrincipalCollection(
				principalCollection, getName());
		super.clearCachedAuthorizationInfo(principals);
	}
}
